#include "debug.h"
#include <SDL/SDL_image.h>
#include "Elements\\CheckBox.h"

using namespace SDL::UTILS;

NS_BEGIN(SDL)
NS_BEGIN(ELEMENTS)

Surface* CheckBox::IMG_RELEASED = NULL;
Surface* CheckBox::IMG_HOVERED = NULL;
Surface* CheckBox::IMG_PRESSED = NULL;
Surface* CheckBox::IMG_CLICKED = NULL;
Surface* CheckBox::IMG_DISABLED = NULL;
Surface* CheckBox::IMG_CHECKED = NULL;

#pragma region CTOR & DTOR

CheckBox::CheckBox(std::wstring const& _text) : AButton(_text), m_checked(false)
{
	CTOR("CheckBox", this);
	if (CheckBox::IMG_RELEASED == NULL)
	{
		CheckBox::IMG_RELEASED = new Surface(
			IMG_Load((*m_resGroup)["CheckBox_released"]->Path.c_str()), true);
		CheckBox::IMG_HOVERED = new Surface(
			IMG_Load((*m_resGroup)["CheckBox_hovered"]->Path.c_str()), true);
		CheckBox::IMG_PRESSED = new Surface(
			IMG_Load((*m_resGroup)["CheckBox_pressed"]->Path.c_str()), true);
		CheckBox::IMG_CLICKED = new Surface(
			IMG_Load((*m_resGroup)["CheckBox_clicked"]->Path.c_str()), true);
		CheckBox::IMG_CHECKED = new Surface(
			IMG_Load((*m_resGroup)["CheckBox_checked"]->Path.c_str()), true);
		CheckBox::IMG_DISABLED = new Surface(
			IMG_Load((*m_resGroup)["CheckBox_disabled"]->Path.c_str()), true);
	}

	m_imgReleased = IMG_RELEASED;
	m_imgHovered = IMG_HOVERED;
	m_imgPressed = IMG_PRESSED;
	m_imgClicked = IMG_CLICKED;
	m_imgDisabled = IMG_DISABLED;

	m_surface = m_imgReleased;
	m_imgChecked = IMG_CHECKED;
	m_imgChecked->SetColorKey(0xFF00FF);
	this->SetPosition(0, 0);
}

CheckBox::CheckBox(CheckBox const& _checkBox) : AButton(*(AButton*)this)
{
	CTOR("CheckBox", this);
	*this = _checkBox;
}

CheckBox::~CheckBox()
{
	DTOR("CheckBox", this);
	m_surface = NULL;
}

#pragma endregion
#pragma region Operators

CheckBox& CheckBox::operator=(CheckBox const& _checkBox)
{
	if (this != &_checkBox)
	{
		*((AButton*)this) = *((AButton*)&_checkBox);
		m_checked = _checkBox.IsChecked();
		m_imgChecked = _checkBox.m_imgChecked;
	}
	return (*this);
}

#pragma endregion

void CheckBox::UpdateState()
{
	if (m_surface == NULL)
		return ;

	if (m_disabled == true)
	{
		m_surface = m_imgDisabled;
		return ;
	}

	int x = 0, y = 0;
	Uint8 button = SDL_GetMouseState(&x, &y);
	Rect mouse(x, y);
	Rect rSurface(m_position.GetX(), m_position.GetY(),
				 m_surface->GetW(), m_surface->GetH());

	if (Rect::IsInArea(mouse, rSurface))
	{
		if (button & SDL_BUTTON_LMASK)
		{
			m_state = BUTTON::STATE::PRESSED;
			m_surface = m_imgPressed;
		}
		else
		{
			if (m_state == BUTTON::STATE::PRESSED)
			{
				m_state = BUTTON::STATE::CLICKED;
				m_surface = m_imgClicked;
				m_checked = !m_checked;
			}
			else
			{
				m_state = BUTTON::STATE::HOVERED;
				m_surface = m_imgHovered;
			}
		}
	}
	else
	{
		m_state = BUTTON::STATE::RELEASED;
		m_surface = m_imgReleased;
	}
}

bool CheckBox::Draw(SDL_Surface* _screen)
{
	if (m_hidden == false)
	{
		if (m_surface != NULL)
		{
			m_surface->BlitSurface(NULL, _screen, &m_position);
			if (m_checked == true)
				m_imgChecked->BlitSurface(NULL, _screen, &m_position);
			m_text.Draw(_screen);
		}
		else
			return (false);
	}
	return (true);
}

void CheckBox::SetPosition(Sint16 _x, Sint16 _y)
{
	m_position.SetX(_x);
	m_position.SetY(_y);
	m_text.SetPosition(_x + m_surface->GetW() + 8,
					   _y + (m_surface->GetH() / 2 - m_text.GetSurface()->GetH() / 2));
}

void CheckBox::SetPosition(Rect const& _position)
{
	this->SetPosition(_position.GetX(), _position.GetY());
}

void CheckBox::Move(Sint16 _offsetX, Sint16 _offsetY)
{
	this->SetPosition(m_position.GetX() + _offsetX, m_position.GetY() + _offsetY);
}

void CheckBox::Move(Rect const& _offset)
{
	this->Move(_offset.GetX(), _offset.GetY());
}

#pragma region Getters & Setters

bool CheckBox::IsChecked() const
{
	return (m_checked);
}

void CheckBox::Check(bool _value)
{
	m_checked = _value;
}

void CheckBox::SetText(std::wstring const& _text)
{
	m_text.Render(_text, Font::RenderBlended);
	this->SetPosition(m_position.GetX(), m_position.GetY());
}

#pragma endregion

NS_END(ELEMENTS)
NS_END(SDL)
